home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene Storm
/
Scene Storm - Volume 1.iso
/
coding
/
c
/
lha_axeman
/
lhext.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-01
|
6KB
|
304 lines
/*----------------------------------------------------------------------*/
/* LHarc Extract Command */
/* This is part of LHarc UNIX Archiver Driver */
/* */
/* Copyright(C) MCMLXXXIX Yooichi.Tagawa */
/* */
/* V0.00 Original 1988.05.23 Y.Tagawa */
/* V1.00 Fixed 1989.09.22 Y.Tagawa */
/* V0.03 LHa for UNIX 1991.12.17 M.Oki */
/*----------------------------------------------------------------------*/
#include "lharc.h"
extern int decode_lzhuf ();
static boolean inquire_extract(char *name)
{
struct stat stbuf;
if(stat (name, &stbuf) >= 0)
{
if(!is_regularfile (&stbuf))
{
error ("Already exist (not a file)", name);
return FALSE;
}
if(noexec)
{
printf ("EXTRACT %s but file is exist.\n", name);
return FALSE;
}
else if(!force)
{
if(!isatty(0)) return FALSE;
switch (inquire("OverWrite ?(Yes/No/All)", name, "YyNnAa"))
{
case 0:
case 1: /* Y/y */
break;
case 2:
case 3: /* N/n */
return FALSE;
case 4:
case 5: /* A/a */
force = TRUE;
break;
}
}
}
if(noexec) printf ("EXTRACT %s\n", name);
return TRUE;
}
static boolean make_parent_path(char *name)
{
char path[FILENAME_LENGTH];
struct stat stbuf;
register char *p;
/* make parent directory name into PATH for recursive call */
strcpy (path, name);
for(p = path + strlen (path); p > path; p--)
if(p[-1] == '/')
{
*--p = '\0';
break;
}
if(p == path)
{
message("Why?", "ROOT");
return FALSE; /* no more parent. */
}
if(stat(path, &stbuf) >= 0)
{
if(is_directory (&stbuf)) return TRUE;
error ("Not a directory", path);
return FALSE;
}
errno = 0;
if(verbose) printf("Making directory \"%s\".", path);
if(mkdir(path, 0777) >= 0)/* try */
return TRUE; /* successful done. */
errno = 0;
if(!make_parent_path(path))
return FALSE;
if(mkdir(path, 0777) < 0) /* try again */
{
message("Cannot make directory", path);
return FALSE;
}
return TRUE;
}
static FILE *open_with_make_path(char *name)
{
FILE *fp;
if((fp = fopen(name, WRITE_BINARY)) == NULL)
{
errno = 0;
if(!make_parent_path (name) || (fp = fopen (name, WRITE_BINARY)) == NULL)
error("Cannot extract", name);
errno = 0;
}
return fp;
}
static void adjust_info(char *name, LzHeader *hdr)
{
}
static char *methods[10] =
{
"-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-",
"-lh5-", "-lzs-", "-lz5-", "-lz4-", NULL
};
static void extract_one(FILE *afp, LzHeader *hdr)
{
FILE *fp; /* output file */
char name[257];
int crc;
int method;
boolean save_quiet, save_verbose;
char *q = hdr->name , c;
if( ignore_directory && rindex(hdr->name,'/') )
{
q = (char *)rindex(hdr->name,'/') + 1;
}
else
{
if(*q=='/')
{
q++;
/*
* if OSK then strip device name
*/
if(hdr->extend_type == EXTEND_OS68K || hdr->extend_type == EXTEND_XOSK )
{
do c=(*q++); while( c && c!='/' );
if(!c||!*q) q = "."; /* if device name only */
}
}
}
if(extract_directory)
sprintf(name, "%s/%s", extract_directory, q);
else
strcpy(name, q);
if((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_REGULAR)
{
for(method = 0; ; method++)
{
if(methods[method] == NULL)
{
error("Unknown method skiped ...", name);
return;
}
if(bcmp(hdr->method, methods[method], 5) == 0)
break;
}
reading_filename = archive_name;
writting_filename = name;
if(output_to_stdout || verify_mode)
{
if(noexec)
{
printf("%s %s\n", verify_mode ? "VERIFY" : "EXTRACT",name);
if (afp == stdin)
{
int i = hdr->packed_size;
while(i--) fgetc(afp);
}
return;
}
save_quiet = quiet;
save_verbose = verbose;
if(!quiet && output_to_stdout)
{
printf("::::::::\n%s\n::::::::\n", name);
quiet = TRUE;
verbose = FALSE;
}
else if(verify_mode)
{
quiet = FALSE;
verbose = TRUE;
}
crc = decode_lzhuf(afp, stdout, hdr->original_size, hdr->packed_size, name, method);
quiet = save_quiet;
verbose = save_verbose;
}
else
{
if(!inquire_extract(name)) return;
if(noexec)
{
if(afp == stdin)
{
int i = hdr->packed_size;
while(i--) fgetc(afp);
}
return;
}
signal(SIGINT, interrupt);
unlink (name);
errno = 0;
remove_extracting_file_when_interrupt = TRUE;
if((fp = open_with_make_path (name)) != NULL)
{
crc = decode_lzhuf(afp, fp, hdr->original_size, hdr->packed_size, name, method);
fclose (fp);
}
remove_extracting_file_when_interrupt = FALSE;
signal (SIGINT, SIG_DFL);
if(!fp) return;
}
errno = 0;
if(hdr->has_crc && crc != hdr->crc) error("CRC error", name);
}
else if((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY)
{
if(!ignore_directory && !verify_mode)
{
if(noexec)
{
printf ("EXTRACT %s (directory)\n", name);
return;
}
/* NAME has trailing SLASH '/', (^_^) */
if(!output_to_stdout && !make_parent_path (name))
return;
}
}
else
{
error ("Unknown information", name);
}
if(!output_to_stdout) adjust_info (name,hdr);
}
/*----------------------------------------------------------------------*/
/* EXTRACT COMMAND MAIN */
/*----------------------------------------------------------------------*/
void cmd_extract()
{
LzHeader hdr;
long pos;
FILE *afp;
/* open archive file */
if((afp = open_old_archive ()) == NULL)
fatal_error (archive_name);
if(archive_is_msdos_sfx1 (archive_name))
skip_msdos_sfx1_code (afp);
/* extract each files */
while(get_header (afp, &hdr))
{
if (need_file (hdr.name))
{
pos = ftell (afp);
extract_one (afp, &hdr);
fseek (afp, pos + hdr.packed_size, SEEK_SET);
}
else
{
if(afp != stdin)
fseek (afp, hdr.packed_size, SEEK_CUR);
else
{
int i = hdr.packed_size;
while(i--) fgetc(afp);
}
}
}
/* close archive file */
fclose (afp);
return;
}